﻿using ASmile.Com.Menu;
using ASmile.DBModel;
using ASmile.Extend;

namespace ASmile.Com.Da
{
    public class MenuBLL : BLLBase, IMenuBLL
    {
        public ApiResultList<Sys_Menu> GetAllMenus()
        {
            var r = DB.Query<Sys_Menu>(s => true).ToList();
            return ApiResult.RetOK(r, r.Count);
        }

        #region 树形结构的操作

        /// <summary>
        /// 菜单分类列表（非菜单的树形结构）
        /// </summary>
        public ApiResultList<Sys_Menu> GetTreeData()
        {
            var query = DB.CreateQuery<Sys_Menu>();
            //query.WhereAnd(s => s.IsMenu == false);
            query.OrderBy(s => s.OrderNo);
            var r = DB.Query<Sys_Menu>(query).ToList(true);
            return RetOK(r, r.Count);
        }
        /// <summary>
        /// 验证model
        /// </summary>
        ApiResult<string> VerifyTreeModel(Sys_Menu m, bool isAdd)
        {
            if (m.MenuCaption.IsEmpty())
            {
                return ApiResult.RetErr(nameof(m.MenuCaption), "分类名称不能为空");
            }

            if (DB.QueryExist<Sys_Menu>(s => s.Id != m.Id && m.MenuCaption == m.MenuCaption))
            {
                return ApiResult.RetErr(nameof(m.MenuCaption), "分类名称已经存在");
            }
            return ApiResult.RetOK(string.Empty, "保存成功！");
        }
        /// <summary>
        /// 新增树
        /// </summary>
        public ApiResult<string> AddTree(Sys_Menu m)
        {
            var ret = VerifyTreeModel(m, true);
            if (!ret)
            {
                return ret;
            }
            if (DB.QueryExist<Sys_Menu>(s => s.PId == m.PId && s.MenuCaption == m.MenuCaption))
            {
                return ApiResult.RetErr(nameof(m.MenuCaption), "当前节点下菜单名称重复");
            }
            //if (DB.QueryExist<Sys_Menu>(s => s.PId == m.PId && s.IsMenu == true))
            //{
            //    return ApiResult.RetErr(string.Empty, "当前菜单分类已经分配菜单，不允许增加子级分类");
            //}
            m.Id = NewId();
            var r = DB.Insert(m);
            if (r.RowCount == 1)
            {
                return ApiResult.RetOK(m.Id, "增加成功");
            }
            return ret;
        }
        /// <summary>
        /// 编辑树
        /// </summary>
        public ApiResult<string> EditTree(Sys_Menu m)
        {
            var ret = VerifyTreeModel(m, false);
            if (!ret)
            {
                return ret;
            }

            var r = DB.Update(m);

            if (r.RowCount == 1)
            {
                return ApiResult.RetOK(string.Empty, "更新成功");
            }
            return ret;
        }
        /// <summary>
        /// 删除树
        /// </summary>
        public ApiResult DelTree(Sys_Menu m)
        {
            if (DB.QueryExist<Sys_Menu>(s => s.PId == m.Id))
            {
                return ApiResult.RetErr("请先移除所子级节点及菜单");
            }
            var ret = DB.Delete<Sys_Menu>(s => s.Id == m.Id);
            if (ret.RowCount == 1)
            {
                return ApiResult.RetOK("删除成功");
            }
            return ApiResult.RetErr("删除失败");
        }

        #endregion

        ApiResult<string> VerifyMenuModel(Sys_Menu model, bool isAdd)
        {
            if (model.PId.IsEmpty())
            {
                return ApiResult.RetErr(nameof(model.MenuCaption), "上级菜单不能为空");
            }
            if (model.MenuCaption.IsEmpty())
            {
                return ApiResult.RetErr(nameof(model.MenuCaption), "菜单标题不能为空");
            }
            if (model.MenuName.IsEmpty())
            {
                return ApiResult.RetErr(nameof(model.MenuName), "菜单名称不能为空");
            }
            if (DB.QueryExist<Sys_Menu>(s => s.MenuName == model.MenuName && s.Id != model.Id))
            {
                return ApiResult.RetErr(nameof(model.MenuName), "菜单名称已经存在");
            }
            if (isAdd)
            {
                model.Id = NewId();
                return RetOK(model.Id, "新增成功");
            }
            else
            {
                return RetOK(string.Empty, "更新成功");
            }
        }

        public ApiResult<string> AddMenu(Sys_Menu model)
        {
            var ret = VerifyMenuModel(model, true);
            if (!ret)
            {
                return ret;
            }
            model.Id = NewId();
            model.IsMenu = true;
            DB.Insert(model);
            return ApiResult.RetOK(string.Empty, "增加菜单成功");
        }

        public ApiResult<string> EditMenu(Sys_Menu model)
        {
            var ret = VerifyMenuModel(model, false);
            if (!ret)
            {
                return ret;
            }

            DB.Update(
                new Sys_RoleMenu { MenuName = model.MenuName },
                s => s.MenuId == model.Id && s.MenuName != model.MenuName);

            DB.Update(model);
            return ApiResult.RetOK(string.Empty, "修改菜单成功");
        }

        public ApiResult DelMenu(Sys_Menu model)
        {
            DB.Delete<Sys_Menu>(s => s.Id == model.Id);
            return ApiResult.RetOK("删除成功！");
        }

        /// <summary>
        /// 根据父级Id获取所有子菜单
        /// </summary>
        public ApiResultList<Sys_Menu> GetMenus(ArgSearchMenu arg)
        {
            var query = DB.CreateQuery<Sys_Menu>();
            query.WhereAnd(s => s.PId == arg.PId && s.IsMenu == true);
            if (!arg.SearchVal .IsEmpty())
            {
                string likeStr = $"%{arg.SearchVal}%";
                query.WhereAnd(s =>
                    s.WEx_Like(s.MenuCaption, likeStr) ||
                    s.WEx_Like(s.MenuName, likeStr));
            }
            query.OrderBy(s => s.OrderNo);
            var dt = DB.Query<Sys_Menu>(query).ToList();
            return ApiResult.RetOK(dt, 0);
        }
        /// <summary>
        /// 交换两个记录的排序
        /// </summary>
        public ApiResult SwapOrderNo(ArgSwapOrderNo arg)
        {
            if (arg.SrcId.IsEmpty() || arg.SrcId.IsEmpty())
            {
                return RetOK("参数错误");
            }
            Sys_Menu model = new Sys_Menu();
            model.Id = arg.SrcId;
            model.OrderNo = arg.TarOrderNo;
            DB.Update(model);
            model.Id = arg.TarId;
            model.OrderNo = arg.SrcOrderNo;
            DB.Update(model);
            return RetOK("交换位置成功");
        }

        public ApiResult SetOrderNo(ArgSetSortNo arg)
        {
            Sys_Menu menu = new Sys_Menu
            {
                Id = arg.Id,
                OrderNo = arg.SortNo
            };
            DB.Update(menu);
            return RetOK("更新排序成功");
        }

        public ApiResult SetParent(ArgSetParent arg)
        {
            Sys_Menu model = new Sys_Menu
            {
                Id = arg.SrcId,
                PId = arg.TarPId,
                OrderNo = arg.OrderNo
            };
            var ret = DB.Update(model);
            if (ret.RowCount == 1)
            {
                return RetOK("更新父级成功");
            }
            else
            {
                return RetOK("更新父级失败");
            }
        }
    }
}
